package com.gm.commonlib.network.basenetwork;

import com.gm.commonlib.network.ObserverImpl;
import com.gm.commonlib.network.basenetwork.config.HttpOptions;
import com.gm.commonlib.network.basenetwork.gson.GsonUtil;
import com.gm.commonlib.network.basenetwork.interfaces.IGetHttpBaseUrl;
import com.gm.commonlib.network.basenetwork.ssl.HostnameVerifierImpl;
import com.youth.banner.util.LogUtils;

import java.io.File;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
public class BaseHttpClient {
    private static BaseHttpClient httpclient;
    public Retrofit sRetrofit;
    public HttpOptions.Builder options;
    public IGetHttpBaseUrl iGetHttpBaseUrl;
    private long DEFAULT_READ_TIMEOUT_MILLIS = 30;
    private long DEFAULT_WRITE_TIMEOUT_MILLIS = 30;
    private long DEFAULT_CACHE_SIZE = 10 * 1024 * 1024;

    public static BaseHttpClient getHttpclient() {
        if (httpclient == null) {
            httpclient = new BaseHttpClient();
        }
        return httpclient;
    }

    public void destory() {
        sRetrofit = null;
        httpclient = null;
    }

    public <T> T createService(Class<T> service) {
        return getRetrofitInstanse().create(service);
    }

    private BaseHttpClient() {
    }


    public void reset() {
        sRetrofit = null;
    }

    public void init(HttpOptions.Builder options, IGetHttpBaseUrl iGetHttpBaseUrl) {
        this.options = options;
        this.iGetHttpBaseUrl = iGetHttpBaseUrl;
    }

    /**
     * 获取retrofit客户端
     *
     * @return
     */
    public Retrofit getRetrofitInstanse() {
        if (sRetrofit == null) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder()
                    .hostnameVerifier(new HostnameVerifierImpl())
                   // .sslSocketFactory(SslSocketFactoryImpl.getSslSocketFactory())
                    .connectTimeout(DEFAULT_READ_TIMEOUT_MILLIS, TimeUnit.SECONDS)
                    .readTimeout(DEFAULT_READ_TIMEOUT_MILLIS, TimeUnit.SECONDS)
                    .writeTimeout(DEFAULT_WRITE_TIMEOUT_MILLIS, TimeUnit.SECONDS);
            initHttpOptions(builder);
            OkHttpClient client = builder.build();
            sRetrofit = new Retrofit.Builder()
                    .baseUrl(iGetHttpBaseUrl.getBaseUrl())
                    //增加返回值为Gson的支持(以实体类返回)
                    .addConverterFactory(GsonConverterFactory.create(GsonUtil.getFormatedGson()))
                    //增加返回值为Oservable<T>的支持
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(client)
                    .build();
        }
        return sRetrofit;
    }

    //初始化网络请求相关参数
    public void initHttpOptions(OkHttpClient.Builder builder) {
        if (options != null) {
            if (options.connectTimeout > 0) {
                builder.connectTimeout(options.connectTimeout, TimeUnit.SECONDS);
            }
            if (options.readTimeout > 0) {
                builder.readTimeout(options.readTimeout, TimeUnit.SECONDS);
            }
            if (options.writeTimeout > 0) {
                builder.writeTimeout(options.writeTimeout, TimeUnit.SECONDS);
            }
            if (options.cacheFile != null) {
                File cacheFile = options.cacheFile;
                makeFolderExists(cacheFile);
                Cache cache;
                if (cacheFile.exists()) {
                    if (options.cacheSize > 0) {
                        DEFAULT_CACHE_SIZE = options.cacheSize;
                    }
                    cache = new Cache(cacheFile, DEFAULT_CACHE_SIZE);
                    builder.cache(cache);
                } else {
                    LogUtils.d("缓存不存在！");
                }
            }
            if (!options.mInterceptors.isEmpty()) {
                for (Interceptor interceptor : options.mInterceptors) {
                    builder.addInterceptor(interceptor);
                }
            }

        }
    }

    public static void makeFolderExists(File file) {
        if (file != null && !file.exists()) {
            file.mkdirs();
        }

    }


    public <T> void sendRequest(final Observable<T> observable,
                                final ObserverImpl<T> observer) {
        final SubscriptionHolder subscriptionHolder = new SubscriptionHolder();
        try {
            observable
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<T>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            subscriptionHolder.setSubscription(d);
                            if (observer != null) {
                                observer.onSubscribe(d);
                            }
                        }

                        @Override
                        public void onNext(T t) {
                            if (observer != null) {
                                observer.onNext(t);

                            }
                        }

                        @Override
                        public void onError(Throwable e) {
                            if (observer != null) {
                                observer.onError(e);
                            }
                        }

                        @Override
                        public void onComplete() {
                            if (observer != null) {
                                observer.onComplete();
                            }
                        }
                    });
        } catch (Exception e) {
            LogUtils.d(e.toString());
        }

        if (observer != null) {
            observer.onSubscribe(subscriptionHolder.getSubscription());
        }
    }
}
